  
#include "StdAfx.h"
#include "Evaluator.h"

void Evaluator::destroyBFP( ){
	if(BFP){
		map<double, F<double>* >::iterator Ptr = BFP->begin( );
		while(Ptr != BFP->end( )){
			if(Ptr->second) delete Ptr->second;
			Ptr->second = NULL;
			Ptr++;	
			}

		delete BFP;
		BFP=NULL;
		}
	}
void Evaluator::destroy( ){
	destroyBFP( );
	if(solutionFunction) {
		delete solutionFunction;
		solutionFunction=NULL;
		}
	}

Evaluator::Evaluator( GeneSet* GS):
	Context(GS), BFP(NULL), solutionFunction(NULL), XToken(NULL){
	}

Evaluator ::~Evaluator( ){
		destroy( );
	}

void Evaluator::makeSolutionFunction(double Rmin, double Rmax, size_t solFunctionIndex, size_t  FCN){
	if(solFunctionIndex != solutionFunctionNumber){
		destroy( );
		solutionFunctionNumber = solFunctionIndex;
		solutionFunction = new CEvaluatingFunction(Rmin, Rmax, solFunctionIndex, FCN);
		}
	}
void Evaluator::setContext(GeneSet* GS){
	 Context = GS;
	}

F<double>* Evaluator::evaluateAtPoint(double x, const VirtualInvertedListTerm* VILT){
	if(SimplifiedExpression.second){
		return new F<double>(*(SimplifiedExpression.second));
		}
	const Token*	TokenTobeEvaluated;
	if(SimplifiedExpression.first){
			TokenTobeEvaluated  = SimplifiedExpression.first;
		}
	else{
		TokenTobeEvaluated  = VILT;
		}

	SemanticEvaluation SE;
	SE.second = new F<double>( x );  
	SE.second->diff(0,1);
	Context->setValue(XToken, SE);
	SemanticEvaluation SERes(Context->eval(TokenTobeEvaluated)); 
	Context->setValue(XToken, SemanticEvaluation( ));
	if(SERes.second){
		return new F<double>(*SERes.second);
		}
	throw "Unable to evaluate at Pt";
	}


map <double, F<double>* >::iterator  Evaluator::getRandomUnevaluatedPoint( ){
	map <double, F<double>* >::iterator it = BFP->begin( );
	size_t offset = rand( )%BFP->size( );
	while(offset > 0){
		it++;
		offset--;
		};
	while( (it != BFP->end( )) && ( it->second )){
		it++;
		}
	if(it != BFP->end( )) return it;
	it = BFP->begin( );
	while( (it != BFP->end( )) && ( it->second ) ){
		it++;
		}
	 return it;

	}	  /*
	return 6.0;
	double DiffGrade = 0.0f;
	double ValGrade = 0.0f;
map<double, F<double>*>::iterator BFPIterator  = BFP->begin();
		map<double, F<double>*>::iterator ThisIterator  = Function->begin();
		while (ThisIterator != Function->end( )){
			if(BFPIterator->second){
			ValGrade += (fabs(BFPIterator->second->x( ) - ThisIterator->second->x( ))) * VD[0];
			DiffGrade += (fabs(BFPIterator->second->d( 0 ) - ThisIterator->second->d( 0 ))) * VD[1];
				}
			}
	
	return 1.0f/((DiffGrade + ValGrade)+1.0f);	*/
double Evaluator::evaluateCDNAPopulationMember(const VirtualInvertedListTerm* VILT, time_t MaxEvalTime, vector<double> Coeffs){
	if(!solutionFunction) throw _T("No solution function for evaluation Evaluator::evaluateCDNAPopulationMember");
	if(!Context) throw _T("No context for evaluation");
	if(MaxEvalTime <= 0) throw _T("No Time Allocated for evaluation");

	time_t BeginTime = time(NULL);
	time_t EndTime = BeginTime + MaxEvalTime;
	destroyBFP( );
	BFP = new BoundedFunctionPoints(
					solutionFunction->getLowerBound( ),
					solutionFunction->getUpperBound( ),
					solutionFunction->getFitnessCasesNumber( ));

	SimplifiedExpression = Context->eval( VILT );
	XToken = Context->Var1;
	NextToEvaluate  = getRandomUnevaluatedPoint( );
	time_t CurrentTime = time( NULL );
	size_t PtsEvaluated = 0;
	double ValGrade		= 0;
	double valDiffGrade = 0;

	while((CurrentTime < EndTime) && (NextToEvaluate != BFP->end( ))){
			double Val = NextToEvaluate->first;
			F<double>* Ptr = evaluateAtPoint( Val, VILT ); 
			if(NextToEvaluate->second) delete NextToEvaluate->second;
			BFP->setValueAtPoint( Val,  Ptr );
			
			double tryVal = Ptr->x( );
			double solVal = solutionFunction->Function->getValueAtPoint(Val)->x( );
			ValGrade += fabs(solVal  - tryVal);

		    double tryDiffVal = Ptr->d( 0 );
			double solDiffVal = solutionFunction->Function->getValueAtPoint(Val)->d( 0 );
			valDiffGrade += fabs(solDiffVal  - tryDiffVal);
			
			NextToEvaluate  = getRandomUnevaluatedPoint( );
			CurrentTime = time( NULL );
			PtsEvaluated++;
		}
	//solutionFunction->evaluateCDNAStatementSemantics( BFP, Coeffs );
	destroyBFP( );
	if(PtsEvaluated > 0 ){
		double Coeff1 = (valDiffGrade / (double)PtsEvaluated)*3.5;// EvalGrade;
		double Coeff2 = ValGrade / (double)PtsEvaluated;
		return PtsEvaluated/((Coeff1 + Coeff2)+1.0f);
		}

		return 0.0f;
	}

void Evaluator ::draw( ){
	if (solutionFunction) solutionFunction->draw( );
	}

